package com.fc.controller;

import com.fc.Base.BaseController;
import com.fc.model.SNSUserInfo;
import com.fc.model.ShareBean;
import com.fc.model.User;
import com.fc.service.PayFlowService;
import com.fc.service.UserService;
import com.fc.util.Response;
import com.fc.util.WeixinUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import static com.fc.util.ConstantParams.shareAppid;
import static com.fc.util.ConstantParams.shareSecret;


/**
 * Created by chenyan on 16/6/3.
 */
@Controller
public class WeShareController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(WeShareController.class);

    @Resource
    private PayFlowService payFlowService;
    @Autowired
    private UserService userService;

    /**
     * 微信分享功能
     *
     * @param url
     * @param code
     * @return
     */
    @RequestMapping(value = "/WeShare.do")
    @ResponseBody
    public Map<String, Object> getSing(@RequestParam(value = "url") String url, @RequestParam(value = "code") String code) {
        logger.info("CODE：++++" + code);
        Map<String, Object> map = new HashMap<String, Object>();

        if (!code.equals("1")) {
            Map<String, String> result = getUserInfoAccessToken(code);//通过这个code获取access_token
            String openId = result.get("openid");
            String access_token = result.get("access_token");

            SNSUserInfo snsUserInfo = WeixinUtil.getSNSUserInfo(access_token, openId);
            //查询用户信息是否已经记录数据库
            int num = payFlowService.isUserInfoHave(openId);
            if (num == 0) {
                payFlowService.keepUserInfo(snsUserInfo);
            }
            map.put("openId", openId);
        }

        String accessToken = WeixinUtil.getAccessToken();
        //2、获取Ticket
        String jsapi_ticket = WeixinUtil.getTicket(accessToken);
        try {
            url = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //3、时间戳和随机字符串
        String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//随机字符串
        map.put("noncestr", noncestr);
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//时间戳
        map.put("timestamp", timestamp);
        System.out.println("accessToken:" + accessToken + "\njsapi_ticket:" + jsapi_ticket + "\n时间戳：" + timestamp + "\n随机字符串：" + noncestr);
        String str = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        //6、将字符串进行sha1加密
        String signature = WeixinUtil.SHA1(str);
        map.put("signature", signature);
        map.put("appId", shareAppid);

        return map;
    }


    /**
     * 通过code获取用户信息,一个code对应一个accessToken,每日获取无上限
     *
     * @param code
     * @return
     */
    public Map<String, String> getUserInfoAccessToken(String code) {
        JsonObject object = null;
        Map<String, String> data = new HashMap();
        try {
            String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + shareAppid
                            + "&secret=" + shareSecret + "&code=%s&grant_type=authorization_code",
                    code);
            logger.info("request accessToken from url: {}", url);
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String tokens = EntityUtils.toString(httpEntity, "utf-8");
            Gson token_gson = new Gson();
            object = token_gson.fromJson(tokens, JsonObject.class);
            logger.info("request accessToken success. [result={}]", object);
            data.put("openid", object.get("openid").toString().replaceAll("\"", ""));
            data.put("access_token", object.get("access_token").toString().replaceAll("\"", ""));
        } catch (Exception ex) {
            logger.error("fail to request wechat access token. [error={}]", ex);
        }
        return data;
    }

    /**
     * 用于储存openId以及parentId
     *
     * @param openId
     */
    @RequestMapping(value = "/keepId.do")
    @ResponseBody
    public Map<Object, Object> keepId(@RequestParam(value = "openId") String openId, @RequestParam(value = "parentId") String parentId,
                                      @RequestParam(value = "activityId") int activityId) {
        Map<Object, Object> data = new HashMap();

        int shareState = 1;
        ShareBean share = payFlowService.selectConnectionInfo(openId, parentId, activityId);
        ShareBean share1 = payFlowService.selectUserActivity(openId, activityId);

        data.put("redEnvelope", "您已经获得红包了！");
        if (share == null) {
            payFlowService.insertId(openId, parentId, shareState);
        } else if (share.getShareState() == 2) {
            payFlowService.updateShareState(openId, parentId, activityId);
        }
        Double ArrayNum = Math.random() + 0.1;
        DecimalFormat df = new DecimalFormat("#.00");
        ArrayNum = Double.parseDouble(df.format(ArrayNum));
        if (share1 == null) {
            payFlowService.insertUserActivity(openId, activityId, shareState, ArrayNum);
            data.put("redEnvelope", "获得" + ArrayNum + "元红包");
        } else if (share1.getShareState() == 2) {
            payFlowService.updateUserActivity(openId, activityId, ArrayNum);
            data.put("redEnvelope", "获得" + ArrayNum + "元红包");
        }

        return data;
    }

    /**
     * 取消分享
     *
     * @param openId
     */
    @RequestMapping(value = "/cancleShare.do")
    @ResponseBody
    public void cancleShare(@RequestParam(value = "openId") String openId, @RequestParam(value = "parentId") String parentId,
                            @RequestParam(value = "activityId") int activityId) {
        ShareBean share = payFlowService.selectConnectionInfo(openId, parentId, activityId);
        int shareState = 2;
        if (share == null) {
            payFlowService.insertId(openId, parentId, shareState);
        }
        ShareBean share1 = payFlowService.selectUserActivity(openId, activityId);
        if (share1 == null) {
            int redEnvelope = 0;
            payFlowService.insertUserActivity(openId, activityId, shareState, redEnvelope);
        }
    }

    @RequestMapping(value = "/payment.do")
    @ResponseBody
    public synchronized Object payment(int uid, BigDecimal money){
        User user = userService.selectUserByUid(uid);
        if((user.getMoney().subtract(money)).compareTo(new BigDecimal(0)) < 0){
            return new Response().fail().code(1).msg("余额不足");
        }
        user.setMoney(user.getMoney().subtract(money));
        userService.updateUser(user);
        return new Response().success().code(0).msg("成功").data(user);
    }
}
